package gov.pbc.nn.kjgl.AbroadApproval.view;

import java.util.Collection;
import java.util.Map;

import javax.annotation.Resource;

import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.GetTableUtils;
import gov.pbc.nn.kjgl.AbroadApproval.dao.A2TaskDao;
import gov.pbc.nn.kjgl.AbroadApproval.entity.A2TaskEntity;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.StartProcessInfo;
import com.bstek.ureport.el.common.StringUtils;

@Component
public class A2TaskPR {
	
	@Autowired
	private A2TaskDao a2TaskDao;
	
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;

	@Resource(name = ProcessClient.BEAN_ID)
	private ProcessClient pc;

	@Resource(name = TaskClient.BEAN_ID)
	private TaskClient tc;

	@DataProvider
	public void loadTasks(Page<A2TaskEntity> page, Criteria criteria)
			throws Exception {
		DetachedCriteria dc = this.a2TaskDao.buildDetachedCriteria(criteria,
				A2TaskEntity.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.addOrder(Order.desc("createDate"));
		this.a2TaskDao.pagingQuery(page, dc);
	}
	
	@DataProvider
	public void loadSelfTasks(Page<A2TaskEntity> page, Criteria criteria)
			throws Exception {
		DetachedCriteria dc = this.a2TaskDao.buildDetachedCriteria(criteria,
				A2TaskEntity.class);
		
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("createUser", ContextHolder.getLoginUserName()));
		dc.addOrder(Order.desc("createDate"));
		this.a2TaskDao.pagingQuery(page, dc);
	}
	@DataProvider
	public void loadTasksInvalid(Page<A2TaskEntity> page, Criteria criteria)
			throws Exception {
		DetachedCriteria dc = this.a2TaskDao.buildDetachedCriteria(criteria,
				A2TaskEntity.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("processopen", true));
		this.a2TaskDao.pagingQuery(page, dc);
	}
	@DataProvider
	public void loadTasksNotInvalid(Page<A2TaskEntity> page, Criteria criteria)
			throws Exception {
		DetachedCriteria dc = this.a2TaskDao.buildDetachedCriteria(criteria,
				A2TaskEntity.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("processopen", false));
		this.a2TaskDao.pagingQuery(page, dc);
	}
	
	@DataProvider
	public Collection<Opinion> getOpinions(String taskEntityId)
			throws Exception {
		return UfloUtils.getOpinions(null, taskEntityId, null, null,null);
	}
	
	// 1已完成，2正在审批，0未提交
	@Transactional
	@Expose
	public int canModify(String id) {
		if (UfloUtils.hasHistoryProcessInstance(id))
			return 1;
		else if (UfloUtils.isInProcessInstance(id))
			return 2;
		else
			return 0;
	}
	
	@Transactional
	@Expose
	public int canDelete(String id) {
		boolean rs = UfloUtils.isInProcessInstance(id);
		return rs ? 0 : 1;
	}
	
	@Transactional
	@DataResolver
	@Expose
	public void deleteTask(A2TaskEntity a2TaskEntity) throws Exception {
		this.a2TaskDao.delete(a2TaskEntity);
	}
	
	@Transactional
	@DataResolver
	@Expose
	public void deleteTaskForce(A2TaskEntity a2TaskEntity) throws Exception {
		A2TaskEntity task = EntityUtils.toEntity(a2TaskEntity);
		String bid = task.getId();
		
		UfloUtils.deleteProcessInstance(bid,true);

		
	}
	
	@DataProvider
	public A2TaskEntity loadTask(String id) throws Exception {
		if (StringUtils.isEmpty(id)) {
			return null;
		}
		A2TaskEntity a2TaskEntity = (A2TaskEntity) this.a2TaskDao.getSession()
				.get(A2TaskEntity.class, id);
		return a2TaskEntity;
	}
	
	@Transactional
	@DataResolver
	@Expose
	public void saveTask(A2TaskEntity a2TaskEntity) throws Exception {
		A2TaskEntity task = EntityUtils.toEntity(a2TaskEntity);
		EntityState state = EntityUtils.getState(task);
		
		if(state.equals(EntityState.NEW)){
			this.a2TaskDao.save(task);
		}
		else if(state.equals(EntityState.MODIFIED)){
			this.a2TaskDao.update(task);
		}
		else if(state.equals(EntityState.DELETED)){
			this.a2TaskDao.delete(task);
		}
		
	}
	
	private void completeTask(String taskEntityId,String taskId,String opinion,Map<String, Object> variables){
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		if(variables!=null) {
			this.pc.saveProcessVariables(task.getProcessInstanceId(), variables);
		}
		final Opinion o = new Opinion();
		o.setBusTable(GetTableUtils.getTablename(A2TaskEntity.class));
		o.setBusKey(taskEntityId);
		o.setOpinion(opinion);
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName("因私出国审批");
		o.setTaskId(ltaskId);
		o.setTaskName(task.getTaskName());
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.coreHibernateDao.save(o);		
		this.tc.start(ltaskId);
		this.tc.complete(ltaskId);
	}
	
	@Expose
	@Transactional
	public void startProcess(Map<String, Object> params) throws Exception {
		String taskEntityId = (String) params.get("taskEntityId");
		String taskId = (String) params.get("taskId");


		if (StringUtils.isNotEmpty(taskId)) {
			this.completeTask(taskEntityId, taskId, "修改后重新提交申请", params);			
		} else {
			// 默认的事项开始流程			
			StartProcessInfo spi = new StartProcessInfo();
			spi.setBusinessId(taskEntityId);
			spi.setPromoter(ContextHolder.getLoginUserName());
			spi.setCompleteStartTask(true);
			spi.setVariables(params);
			this.pc.startProcessByName("因私出国审批", spi);
		}
	}
	
	@Transactional
	@Expose
	public void cancelProcess(Map<String, Object> params) throws Exception {
		String taskEntityId = (String) params.get("taskEntityId");
		String taskId = (String) params.get("taskId");
		long ltaskId = Long.parseLong(taskId);
		Task task = this.tc.getTask(ltaskId);
		final Opinion o = new Opinion();
		o.setBusKey(taskEntityId);
		o.setOpinion("申请人撤销申请");
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setProcessName("因私出国审批");
		o.setTaskId(ltaskId);
		o.setTaskName(task.getTaskName());
		o.setNodeName(task.getNodeName());
		o.setUsername(ContextHolder.getLoginUserName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		this.coreHibernateDao.save(o);	
		this.tc.forward(ltaskId, "审批结束");
	}
	
	
}
